import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Creared with IntelliJ IDEA.
 * Description:
 * User:yxd
 * Date:2022-06-02
 * Time:17:58
 */
class  Message{
    public String from;
    public String to;
    public String message;
}
//这里的路径也是约定好的,不是随便写的
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    //使用Jackon对象来处理json格式的body
    private ObjectMapper objectMapper = new ObjectMapper();
    //设置一个list存放取出来的Message对象
    //private List<Message> messages = new ArrayList<>();
    //如果存到数据库当中的话,就不需要这个list数组了,直接存储到数据库就看有了
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //使用jackson对象的核心方法来处理请求中的数据
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //保存对象最简单的方法就是保存到内存中去 而这样的存储方式是存到内存中,当服务器刷新之后,这些信息就消失了,因此想要存储方式是持久化的就需要将信息存到硬盘中去,而想要存储在硬盘中有两种方式:存到数据库中,或者存储在文件中,而这里就选择存储在数据库中
        //而想要存储在数据库中,就需要先引入依赖,然后这里存储的时候就不是放到这个数组中了,而是通过方法将这个对象存储到数据库当中去
        //messages.add(message);
        save(message);
        //设置Content-Type保证能够识别json格式
        //有了这样的声明,此时jquery ajax就会自动帮我们把字符串转换为js对象了.如果没有这样的声明,jquery ajax就只会把这个当成普通的字符串来处理
        resp.setContentType("application/json;charset=utf8");
        //返回约定好的body内容 不能少些{}
        resp.getWriter().write("{ \"ok\":true }");

    }

    private void save(Message message) {
        //将一条消息保存到数据库当中去

        Connection connection = null;
        PreparedStatement statement = null;
        try {
            //1.建立连接
            connection = Message_mysql.getConnection();
            //2.构造sql语句
            String sql = "insert into wall values(?,?,?)";
            //将sql语句放入
            statement = connection.prepareStatement(sql);
            statement.setString(1,message.from);
            statement.setString(2,message.to);
            statement.setString(3,message.message);
            //然后执行sql语句
            statement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //然后释放资源
            Message_mysql.close(connection,statement,null);
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获得消息列表 此处就只需要把消息列表的内容返回给客户端就可以了
        //而通过objectMapper不仅可以将字符串转换为对象,而且可以将对象转换成JSON格式的字符串(通过writeValueAsString方法即可)

        /*
        而如果改成从数据中读取消息的话就是直接从数据库中读取消息,然后全部放到一个数组中,在通过objectMapper的这个犯法将对象转化为字符串
         */
        List<Message> messages = load();
        String jsonString = objectMapper.writeValueAsString(messages);
        //这里可以将转换后的字符串打印出来看一下
        System.out.println(jsonString);
        resp.setContentType("application/json;charset=utf8");

        //然后将转换后的结果放入body即可
        resp.getWriter().write(jsonString);
    }

    private List<Message> load() {
        //读取数据库当中的数据

        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        List<Message> list = new ArrayList<>();
        try {
            //1.建立连接
            connection = Message_mysql.getConnection();
            //2.构造sql语句
            String sql = "select * from wall";
            //将sql语句放入
            statement = connection.prepareStatement(sql);

            //然后执行sql语句
            resultSet = statement.executeQuery();
            //遍历获得的消息
            while (resultSet.next()){
                Message message = new Message();
                message.from = resultSet.getString("from");
                message.to = resultSet.getString("to");
                message.message = resultSet.getString("message");
                list.add(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //然后释放资源
            Message_mysql.close(connection,statement,resultSet);
        }
        return list;
    }
}



/*
而大部分网站的开发都是类似的情况,基本分成三类MAC:M(Model 操作数据的存取的逻辑) C(Controller 控制器处理请求之后的关键逻辑) V(View 给用户的界面)
V和C进行交互,然后C再和M进行交互,也就完成了前端和后端的交互
 */